

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Monitor {

	private int numeroDeTratadoresDeLinhas;
	private Lock lock = new ReentrantLock();
	private Condition dormitorioDosTratadoresDeLinhas = this.lock.newCondition();
	private int numeroDeTratadoresDeLinhasDormindo;
	private Condition dormitorioDoCoordenador = this.lock.newCondition();

	public Monitor(int numeroDeTratadoresDeLinhas) {
		super();
		this.numeroDeTratadoresDeLinhas = numeroDeTratadoresDeLinhas;
	}

	public void esperaOsTratadoresDeLinhasDormirem() {
		try {
			this.lock.lock();
			if (this.numeroDeTratadoresDeLinhasDormindo != this.numeroDeTratadoresDeLinhas) {
				this.dormitorioDoCoordenador.await();
			}
		} catch (InterruptedException e) {
			System.out.println("A JVM me acordou!");
			e.printStackTrace();
		} finally {
			this.lock.unlock();
		}
	}

	public void acordaOsTratadoresDeLinhas() {
		try {
			this.lock.lock();
			this.numeroDeTratadoresDeLinhasDormindo = 0;
			this.dormitorioDosTratadoresDeLinhas.signalAll();
		} finally {
			this.lock.unlock();
		}
	}

	public void queroDormir() {
		try {
			this.lock.lock();
			if (this.numeroDeTratadoresDeLinhasDormindo == this.numeroDeTratadoresDeLinhas - 1) {
				this.dormitorioDoCoordenador.signal();
			}
			this.numeroDeTratadoresDeLinhasDormindo++;
			this.dormitorioDosTratadoresDeLinhas.await();

		} catch (InterruptedException e) {
			System.out.println("A JVM me acordou!");
			e.printStackTrace();
		} finally {
			this.lock.unlock();
		}
	}

}
